<template>
    <div class="border border-br flex flex-col" :style="styles">
        <toolbar class="border-b border-br" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
        <w-editor class="overflow-y-auto flex-1" v-model="valueHtml" :defaultConfig="editorConfig" :mode="mode" @onCreated="handleCreated" />
        <material-picker ref="materialPickerRef" :type="fileType" :limit="-1" hidden-upload @change="selectChange" />
    </div>
</template>
<script setup lang="ts">
import "@wangeditor/editor/dist/css/style.css" // 引入 css
import { Editor as WEditor, Toolbar } from "@wangeditor/editor-for-vue"
import type { IEditorConfig, IToolbarConfig } from "@wangeditor/editor"
import MaterialPicker from "@/components/material/picker.vue"
import { addUnit } from "@/utils/util"
import type { CSSProperties } from "vue"

const props = withDefaults(
    defineProps<{
        modelValue?: string
        mode?: "default" | "simple"
        height?: string | number
        width?: string | number
        toolbarConfig?: Partial<IToolbarConfig>
    }>(),
    {
        modelValue: "",
        mode: "default",
        height: "100%",
        width: "auto",
        toolbarConfig: () => ({})
    }
)

const emit = defineEmits<{
    (event: "update:modelValue", value: string): void
}>()

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef()
const materialPickerRef = shallowRef<InstanceType<typeof MaterialPicker>>()
const fileType = ref("")

let insertFn: any

const editorConfig: Partial<IEditorConfig> = {
    MENU_CONF: {
        uploadImage: {
            customBrowseAndUpload(insert: any) {
                fileType.value = "image"
                materialPickerRef.value?.showPopup(-1)
                insertFn = insert
            }
        },
        uploadVideo: {
            customBrowseAndUpload(insert: any) {
                fileType.value = "video"
                materialPickerRef.value?.showPopup(-1)
                insertFn = insert
            }
        }
    }
}

const styles = computed<CSSProperties>(() => ({
    height: addUnit(props.height),
    width: addUnit(props.width)
}))
const valueHtml = computed({
    get() {
        return props.modelValue
    },
    set(value) {
        emit("update:modelValue", value)
    }
})

const selectChange = (fileUrl: string[]) => {
    fileUrl.forEach((url) => {
        insertFn(url)
    })
}

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
    const editor = editorRef.value
    if (editor == null) return
    editor.destroy()
})

const handleCreated = (editor: any) => {
    editorRef.value = editor // 记录 editor 实例，重要！
}
</script>

<style lang="scss">
.w-e-full-screen-container {
    z-index: 999;
}
.w-e-text-container [data-slate-editor] ul {
    list-style: disc;
}
.w-e-text-container [data-slate-editor] ol {
    list-style: decimal;
}
h1 {
    font-size: 2em;
}
h2 {
    font-size: 1.5em;
}
h3 {
    font-size: 1.17em;
}
h4 {
    font-size: 1em;
}
h5 {
    font-size: 0.83em;
}
h1,
h2,
h3,
h4,
h5 {
    font-weight: bold;
}
</style>
